package source_api

import (
	"errors"
	"fmt"
	"github.com/buger/jsonparser"
	"github.com/imroc/req"
	"github.com/spf13/viper"
	"strconv"
	"strings"
	"time"
)

const BALANCE_QUERY_PATH = "https://diankong.jluzh.edu.cn/App/DBGetPost.ashx"
const AVERAGE_SAMPLE_DAY = 3 //平均电费样本天数

/* START 格式化函数 */
//保留两位小数
func ToFixed(value float64) float64 {
	value, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", value), 64)
	return value
}

//美化日期 "2021/1/2 0:08:47" -> "2021-01-02"
//layout格式参见：time/format.go:11
func BeautyDate(date string) string {
	d, err := time.Parse("2006/1/2 15:04:05", date) //尝试解析日期

	if err != nil { //解析失败，直接返回替换分隔符格式日期
		return strings.ReplaceAll(strings.Split(date, " ")[0], "/", "-")
	}

	return d.Format("2006-01-02") //格式化后返回
}

//格式化宿舍 "R5-531" -> "榕园五栋 531"
func BeautyRoom(buildingAndRoomName string) string {
	nameArr := strings.Split(buildingAndRoomName, "-")
	buildingEN := nameArr[0]
	room := nameArr[1]
	buildingZH := viper.GetString(buildingEN)

	return buildingZH + " " + room
}

//支付方式简化
func BeautyPayment(payment string) string {
	if len(payment) != 0 {
		return payment[:len(payment)-6]
	}
	return payment
}

/* END 格式化函数 */

//获取余额信息
func (s *ElectricSession) GetBalance(roomDm string) (remainingUsage float64, balance float64, err error) {
	dkResp, _ := req.Post(BALANCE_QUERY_PATH, req.Param{
		"request_type": "query_type",
		"roomdm":       roomDm,
		"roomid":       "",
		"start_date":   "",
		"end_date":     "",
	}, req.Header{
		"User-Agent": USER_AGENT,
		"Cookie":     s.Cookie,
	})

	responseByte := make([]byte, dkResp.Response().ContentLength)

	dkResp.Response().Body.Read(responseByte)
	fmt.Print(string(responseByte))
	defer dkResp.Response().Body.Close()

	remainingUsageString, _ := jsonparser.GetString(responseByte, "data", "[0]", "SYL")
	remainingBalanceString, _ := jsonparser.GetString(responseByte, "data", "[0]", "SYLJE")
	apiCode, _ := jsonparser.GetInt(responseByte, "data", "[0]", "code")

	if apiCode == -2 { //查询数据异常: {"code":-2,"msg":"查询数据异常！"}，一般是宿舍号不存在
		err = errors.New("dormitory room do not exist")
		return
	}

	remainingUsage, _ = strconv.ParseFloat(remainingUsageString, 10)
	balance, _ = strconv.ParseFloat(remainingBalanceString, 10)
	return
}

//获取平均使用量
func (s *ElectricSession) GetAverageUsage(roomDm string) (avgUsage float64) {
	dkResp, _ := req.Post(BALANCE_QUERY_PATH, req.Param{
		"request_type": "query_using",
		"roomdm":       roomDm,
		"roomid":       "",
		"start_date":   "",
		"end_date":     "",
	}, req.Header{
		"User-Agent": USER_AGENT,
		"Cookie":     s.Cookie,
	})

	responseByte := make([]byte, dkResp.Response().ContentLength)

	dkResp.Response().Body.Read(responseByte)
	fmt.Print(string(responseByte))
	defer dkResp.Response().Body.Close()

	threeDayUsage := float64(0)

	for i := 1; i < AVERAGE_SAMPLE_DAY+1; i++ {
		dayUsageString, _ := jsonparser.GetString(responseByte, "data", fmt.Sprintf("[%d]", i), "zyl") //返回json数据是str，卑微
		dayUsage, _ := strconv.ParseFloat(dayUsageString, 10)
		threeDayUsage += dayUsage
	}

	avgUsage = ToFixed(threeDayUsage / 3) //日均电费
	return
}

//电费历史每天数据类型
func (s *ElectricSession) GetHistory(roomDm string) (history []map[string]interface{}) {
	dkResp, _ := req.Post(BALANCE_QUERY_PATH, req.Param{
		"request_type": "query_using",
		"roomdm":       roomDm,
		"roomid":       "",
		"start_date":   "",
		"end_date":     "",
	}, req.Header{
		"User-Agent": USER_AGENT,
		"Cookie":     s.Cookie,
	})

	responseByte := make([]byte, dkResp.Response().ContentLength)

	dkResp.Response().Body.Read(responseByte)
	fmt.Print(string(responseByte))
	defer dkResp.Response().Body.Close()

	var historyArr []map[string]interface{}

	jsonparser.ArrayEach(responseByte, func(value []byte, dataType jsonparser.ValueType, offset int, err error) {
		date, _ := jsonparser.GetString(value, "accounttime")

		dayUsageStr, _ := (jsonparser.GetString(value, "zyl"))
		dayUsage, _ := strconv.ParseFloat(dayUsageStr, 10)

		dayRemainStr, _ := jsonparser.GetString(value, "zye")
		dayRemain, _ := strconv.ParseFloat(dayRemainStr, 10)

		item := make(map[string]interface{})
		item["date"] = date
		item["electricUsage"] = dayUsage
		item["remain"] = dayRemain

		historyArr = append(historyArr, item)

		fmt.Print(historyArr)

	}, "data")

	return historyArr
}

//查询充值记录 studentId: 04181010
func (s *ElectricSession) GetRechargeHistory(studentId string) ([]map[string]interface{}, error) {
	dkResp, _ := req.Post(BALANCE_QUERY_PATH, req.Param{
		"request_type": "czjl_query",
		"studentid":    studentId,
		"start_date":   "",
		"end_date":     "",
	}, req.Header{
		"User-Agent": USER_AGENT,
		"Cookie":     s.Cookie,
	})

	responseByte := make([]byte, dkResp.Response().ContentLength)
	dkResp.Response().Body.Read(responseByte)
	fmt.Print(string(responseByte))
	defer dkResp.Response().Body.Close()

	var historyArr []map[string]interface{}

	jsonStatusCode, jsonStatusCodeErr := jsonparser.GetInt(responseByte, "code")

	if jsonStatusCode == -1 || jsonStatusCodeErr != nil {
		return nil, errors.New("recharge history do not exist")
	}

	jsonparser.ArrayEach(responseByte, func(value []byte, dataType jsonparser.ValueType, offset int, err error) {
		payType, _ := jsonparser.GetString(value, "buytpe")        //充值类型 "微信支付"
		date, _ := jsonparser.GetString(value, "datetime")         //充值日期时间 "2021/1/2 0:08:47"
		money, _ := jsonparser.GetString(value, "money")           //充值金额 "64.6"
		roomName, _ := jsonparser.GetString(value, "roomname")     //房间名 "R5-531"
		electricQuota, _ := jsonparser.GetString(value, "usingds") //充值等额电量 "100"

		temp := make(map[string]interface{})
		temp["payType"] = BeautyPayment(payType)
		temp["date"] = BeautyDate(date)
		temp["money"], _ = strconv.ParseFloat(money, 10)
		temp["roomName"] = BeautyRoom(roomName)
		temp["electricQuota"], _ = strconv.ParseFloat(electricQuota, 10)

		historyArr = append(historyArr, temp)
	}, "data")

	return historyArr, nil
}
